package com.central.apps.service.impl;

import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSON;
import com.central.app.common.cache.CfgRedisCache;
import com.central.app.common.feign.FileClient;
import com.central.app.common.provide.MessageProvide;
import com.central.app.model.BizObject;
import com.central.app.service.AppCommonService;
import com.central.app.service.BizNumberService;
import com.central.app.service.HandlerService;
import com.central.apps.dao.BizCustomDao;
import com.central.apps.service.AppCustomService;
import com.central.bizcommon.model.system.SysDept;
import com.central.common.constant.UserType;
import com.central.common.model.SysRole;
import com.central.common.model.SysUser;
import com.central.common.util.ToolUtil;
import com.central.common.util.ValidatorUtil;
import com.central.common.web.Result;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;
/**
 * @author fuyg
 *
 */
@Slf4j
@Service
public class AppCustomServiceImpl implements AppCustomService {

    private static final Map<String, Object> Object = null;
    @Autowired
    private BizCustomDao customDao;
    @Autowired
    private BizNumberService bizNumberService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private HandlerService handlerService;
    @Autowired
    private FileClient fileClient;
    @Autowired
    private CfgRedisCache cfgRedisCache;
    @Autowired
    private AppCommonService commonService;

    private static final SimpleDateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    //查找最大版本
    @Override
    public Map<String, Object> findMaxVersion(String type) throws Exception{
        return customDao.findMaxVersion(type);
    }

    @Override
    public List<Map<String,Object>> offline(Map<String,Object> params){
        String ids = MapUtils.getString(params, "ids");
        JSONArray array = JSONArray.fromObject(ids);
        StringBuffer stringBuffer = new StringBuffer("select * from bl_workorder where id in (");
        for (int i = 0,size = array.size(); i < size; i++) {
            stringBuffer.append(",");
            stringBuffer.append(array.get(i));
        }
        stringBuffer.append(")");
        String checkOrderSql = stringBuffer.toString().replaceFirst(",", "");
        List<Map<String, Object>> workOrders = handlerService.findBySql(checkOrderSql);
        return workOrders;
    }


    @Override
    public Result checkRequest(String url, Map<String, Object> params) {

        // 根据URL查询bl_interfacerecord 的ID
        Integer id = customDao.findByUrl(url);
        if (ToolUtil.isEmpty(id)) {
            return Result.failed("数据无记录");
        }
        // 根据ID查询所有的参数的特点存入list的集合
        List<Map<String, Object>> dbParams = customDao.findVisit(id);
        if (!CollectionUtils.isEmpty(dbParams)) {
            for (Map<String, Object> dbParam : dbParams) {
                String parameter = MapUtil.getStr(dbParam, "parameter");
                String isRequired = MapUtil.getStr(dbParam, "isRequired");
                String maxLength = MapUtil.getStr(dbParam, "maxLength");
                String parameterType = MapUtil.getStr(dbParam, "parameterType");

                String value = MapUtil.getStr(params, parameter);
                if (value==null){
                    return Result.failed("无此参数:"+parameter);
                }
                if (ToolUtil.isEmpty(value) && "1".equals(isRequired)) {
                    return Result.failed("必填值为空");
                }
                if (Integer.parseInt(maxLength) < value.length()) {
                    return Result.failed("超过最大值");
                }
                // TODO 待问怎么比较类型
                if (!"字符串".equals(parameterType)) {
                    return Result.failed("类型不是字符串");
                }
            }
        }
        return Result.succeed("请求成功");
    }


    @Override
    public String validateRequestHeader(HttpServletRequest request) throws Exception{
        String type = request.getHeader("method_id");
        String sign = request.getHeader("sign");
        if(ToolUtil.isEmpty(sign)){
            return "请求头中无sign信息";
        }
        String sql = "select code,name from sys_dict where pid = (select id from sys_dict where code='signoption') and code='"+type+"'";
        List<Map<String,Object>> signList = handlerService.findBySql(sql);
        if(CollectionUtils.isNotEmpty(signList)){
            for(Map<String,Object> signMap : signList){
                String signValue = MapUtils.getString(signMap,"name");
                if(!signValue.equals(sign)){
                    return "请求头中sign信息不匹配";
                }
            }
        }
        return  null;
    }


    @Transactional
    public Result mainSend(Map<String, Object> data) throws Exception {
        List<Map<String, Object>> mailList = (ArrayList)data.get("data");
        if(!CollectionUtils.isEmpty(mailList)){
            for(int i=0;i<mailList.size();i++){
                Map<String,Object> mainlMap  = mailList.get(i);
                String email = MapUtils.getString(mainlMap,"email");
                String subject = MapUtils.getString(mainlMap,"subject");
                String content = MapUtils.getString(mainlMap,"content");
                if(ToolUtil.isEmpty(email) || ToolUtil.isEmpty(subject) || ToolUtil.isEmpty(content)){
                    return Result.failed("输入参数不完整，请重新填写");
                }
//                if(!checkEmail(email)){
//                    int nowindex = i+1;
//                    return Result.failed("第"+nowindex+"组数据,邮箱格式不正确");
//                }
                MessageProvide.me().sendSimpleMail(email, subject, content);
            }
        }
        return Result.succeed("操作成功");
    }

    @Transactional
    @Override
    public Result userSave(Map<String, Object> data) throws Exception {
        List<Map<String, Object>> userList = (ArrayList)data.get("data");
        int counts =0;
        StringBuilder sbf = new StringBuilder();
        if(!CollectionUtils.isEmpty(userList)){
            for(int i=0;i<userList.size();i++){
                Map<String,Object> userMap  = userList.get(i);
                SysUser user = JSON.parseObject(JSON.toJSONString(userMap), SysUser.class);
                user.setId(null);
                Result result = userDataSave(user,sbf);
                if(result.getCode()==1){
                    String msg = result.getMsg();
                    int nowindex = i+1;
                    result.setMsg("第"+nowindex+"组数据,"+msg);
                    return result;
                }
            }
        }else{
            return Result.succeed("导入数据不能为空");
        }
        if(ToolUtil.isNotEmpty(sbf.toString())){
            handlerService.updateBySql(sbf.toString());
            log.info("sql语句+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"+sbf.toString());
            counts ++;
            log.info("执行次数+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"+counts);
        }else{
            return Result.succeed("导入数据不能为空");
        }
        return Result.succeed("操作成功");
    }

    //@Transactional
    public Result userDataSave(SysUser sysUser,StringBuilder sbf) {
        String username = sysUser.getUsername();
        if (StringUtils.isBlank(username)) {
            return Result.failed("用户名不能为空");
        }

        if (ValidatorUtil.checkPhone(username)) {// 防止用手机号直接当用户名，手机号要发短信验证
            return Result.failed("用户名要包含英文字符");
        }

        if (username.contains("@")) {// 防止用邮箱直接当用户名，邮箱也要发送验证（暂未开发）
            return Result.failed("用户名不能包含@");
        }

        if (username.contains("|")) {
            return Result.failed("用户名不能包含|字符");
        }

        if(StringUtils.isBlank(sysUser.getEmail())){
            return Result.failed("邮箱不能为空");
        }
//        if (!checkEmail(sysUser.getEmail())) {
//            return Result.failed("邮箱格式不正确");
//        }

        if (StringUtils.isBlank(sysUser.getNickname())) {
            sysUser.setNickname(username);
        }

        if (StringUtils.isBlank(sysUser.getWorknumber())) {
            sysUser.setWorknumber(username);
        }

        if (StringUtils.isBlank(sysUser.getType())) {
            sysUser.setType(UserType.APP.name());
        }
        Date date = new Date();
        SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String createtime = sdf.format(date);

        int i = 0;
        if (sysUser.getId() == null) {
            Map<String,Object> persistenceUser = customDao.findByUsername(sysUser.getUsername());
            if (persistenceUser != null && ToolUtil.isNotEmpty(persistenceUser.get("username"))) {
                return Result.failed("用户名已存在");
            }
            Map<String, Object> userMap = customDao.findMapByWorknumber(sysUser.getWorknumber());
            if(userMap != null){
                return Result.failed("工号重复");
            }
            String pwd = passwordEncoder.encode("123456");
//            sysUser.setPassword(pwd);
//            sysUser.setWeiinfo("123456");
//            sysUser.setEnabled(Boolean.TRUE);
//            sysUser.setCreatetime(new Date());
//            sysUser.setUpdatetime(sysUser.getCreatetime());
            //创建人
//            sysUser.setCreateuser("1");
//            sysUser.setDeptcode("D0069");//机构编码
            sbf.append("insert into sys_user(username, password, nickname, worknumber,enabled,type, createtime, createuser, leaveoffice,del_flag,deptcode,weiinfo) " +
                    " values('"+username+"', '"+pwd+"', '"+sysUser.getNickname()+"', '"+sysUser.getWorknumber()+"',1,'"+UserType.APP.name()+"','"+createtime+"','1','0',0,'D0069','123456');");
        }

        return Result.succeed(sysUser, "操作成功");
    }

    @Transactional
    @Override
    public Result deptSave(Map<String,Object> data) throws Exception{
        List<Map<String,Object>> deptList = (ArrayList)data.get("data");
        if(!CollectionUtils.isEmpty(deptList)){
            for(int i=0;i<deptList.size();i++){
                Map<String,Object>  deptMap = deptList.get(i);
                SysDept dept = JSON.parseObject(JSON.toJSONString(deptMap), SysDept.class);
                dept.setId(null);
                dept.setCode(null);
                Result result = deptDataSave(dept);
                if(result.getCode()==1){
                    String msg = result.getMsg();
                    int nowindex = i+1;
                    result.setMsg("第"+nowindex+"组数据,"+msg);
                    return result;
                }
            }
        }
        return Result.succeed("操作成功");
    }

    //@Transactional
    public Result deptDataSave(SysDept dept) throws Exception{
        try {
            if(ToolUtil.isEmpty(dept.getFullname())){
                return Result.succeed("机构名称不能为空");
            }
            String deptnum = bizNumberService.findAndAddSerialNum("system", "dept", null, new HashMap<String, Object>());
            if (deptnum != null && !deptnum.equals("")) {
                //使用while循环，如果生成的编号数据库中已存在，则继续循环生成编号，继续判断，如果不重复则终止循环。
                boolean isrepeat = true;
                while (isrepeat) {
                    if(ToolUtil.isNotEmpty(deptnum)) {
                        Map<String,Object> depts = customDao.findByDeptCode(deptnum);
                        if(depts==null) {
                            isrepeat = false;
                        }else {
                            deptnum = bizNumberService.findAndAddSerialNum("system", "dept", null, new HashMap<String, Object>());
                        }
                    }else {
                        //如果编号为空，可能是编号生成出现不可控因素，如redis服务停掉。无法生成编号，则不再继续while循环，防止编号无法生成时，继续循环耗尽内存。
                        isrepeat = false;
                    }
                }
                dept.setCode(deptnum);
            }
            customDao.deptSave(dept);
            return Result.succeed("操作成功");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.failed("操作失败");
        }
    }

    //public  boolean checkEmail(String email) {return Pattern.matches(REGEX_EMAIL, email);}

    @Override
    public Result changeStatus(Map<String, Object> params){
        String appname = MapUtils.getString(params,"appname");
        String id = MapUtils.getString(params,"id");
        BizObject object = cfgRedisCache.getCacheObjByApp(appname);
        String objName = object.getName();
        String updatetime = DATETIME_FORMAT.format(new Date());
        String updateSql = "update "+objName+" set status='暂停',updatetime='"+updatetime+"' where id="+id;
        String updateFlowSql = "update biz_flow_app set biz_status='暂停',updatetime='"+updatetime+"' where app='"+appname+"' and biz_id="+id;
        handlerService.findBySql(updateSql);
        handlerService.updateBySql(updateFlowSql);
        return Result.succeed("操作成功");
    }

}
